package rgr;

import process.Actor;
import process.DispatcherFinishException;
import process.IWaitCondition;
import queues.QueueForTransactions;
import queues.Store;
import rnd.Randomable;

//Клас для екскалатора
public class Ecsc extends Actor {

	// Купа каміння
	private Store heap;

	// Черга самосвалів, що чекають завантаження
	private QueueForTransactions queueToEcsc;

	// Тривалість роботи екскалатора
	private double finishTime;

	// Генератор часу, що витрачається на одну порцію каміння
	private Randomable rnd;

	//Коструктор, у якому ініціалізуються усі поля класу
	//через доступ до моделі та візуальної частини
	public Ecsc(String name, GUI gui, Model model) {
		setNameForProtocol(name);
		heap = model.getHeep();
		queueToEcsc = model.getQueueToEcsc();
		finishTime = gui.getChooseDataFinishTime().getDouble();
		rnd = gui.getRndEcsc();
	}

	// Правила дії екскалатора
	public void rule() {
		//Обєкти типу IWaitCondition створюються один раз
		//до початку циклу роботи
		
		// Умова наявності каміння у купі
		IWaitCondition heapSize = new IWaitCondition() {
			public boolean testCondition() {
				return heap.getSize() > 0;
			}

			public String toString() {
				return ("має бути каміння у купі");
			}
		};
		// Умова наявності незавантаженого самосвалу
		IWaitCondition isEmptyLorry = new IWaitCondition() {
			public boolean testCondition() {
				return queueToEcsc.size() > 0
						&& !((Lorry) (queueToEcsc.peekFirst())).isFull();
			}

			public String toString() {
				return ("має бути незавантажений самосвал");
			}
		};
		// Правила дії навантажувача
		do {
			// Перевірка наявності грунту у купі
			// і якщо його нема - чекання
	
				try {
					waitForCondition(heapSize);
				} catch (DispatcherFinishException e1) {
					return;
				}
			getDispatcher().printToProtocol(
					getNameForProtocol() + " бере порцію каміння");
			heap.remove(1);
			// Перевірка, чи є незавантажений самоскид
			// і якщо його нема - чекання
			try {
				waitForCondition(isEmptyLorry);
			} catch (Exception e) {
				return;
			}
			// Додаємо каміння у самосвал, що перший у черзі
			getDispatcher().printToProtocol(
					getNameForProtocol()
							+ " додає порцію каміння у самоскид "
							+ ((Lorry) (queueToEcsc.peekFirst()))
									.getNameForProtocol());
			((Lorry) (queueToEcsc.peekFirst())).addPortion();
			//Затримка на час перевантаження
			holdForTime(rnd.next());
		}while (getDispatcher().getCurrentTime() <= finishTime);
	}
}
